package com.zhou.project.result;

import lombok.SneakyThrows;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author zhouhonggang
 * @version 1.0.0
 * @project spring-boot-project
 * @datetime 2022-03-04 16:37
 * @description: TODO
 */
@RestControllerAdvice(basePackages = "com.zhou.project")
public class ResultAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 定义需要拦截的方法
     * @param methodParameter 方法参数
     * @param converterType   目标对象
     * @return  是否拦截
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        return AnnotatedElementUtils.hasAnnotation(methodParameter.getContainingClass(), ResponseBody.class);
    }

    /**
     * 统一封装响应返回结果
     * @param data                  返回结果
     * @param methodParameter       方法参数
     * @param mediaType             返回类型
     * @param aClass                目标对象
     * @param request               请求
     * @param response              响应
     * @return  封装结果集
     */
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object data, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse response) {
        if(data instanceof String)
            return data;
        return ResultData.success(data);
    }

    /**
     * 统一封装错误响应
     * @param exception 异常
     * @return  封装结果集
     */
    @ExceptionHandler(value = Exception.class)
    public ResultData exception(Exception exception) {
        //公共的错误
        return ResultData.failure(ResultEnum.INTERFACE_CALL_ERROR, exception.getMessage());
    }

}
